package cn.b.sky.user;

import cn.b.sky.user.service.model.UserInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;

import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.Set;

public class SecurityContextUtil {

  private static final Logger log = LoggerFactory.getLogger(SecurityContextUtil.class);
  
  private SecurityContextUtil() {
    // Hide the constructor
  }

  /**
   * 取得当前用户的登录名,就是用户code， 如果当前用户未登录则返回空字符串.
   */
  public static String getCurrentUserName() {
    UserInfo user = getCurrentUser();
    return user == null ? "system" : user.getUserCode();
  }

  /**
   * 取得当前用户的登录名,用户描述 如果当前用户未登录则返回空字符串.
   */
  public static String getCurrentUserText() {
    UserInfo user = getCurrentUser();
    return user == null ? "system" : user.getUserText();
  }

  /**
   * 取得当前用户, 返回值为User类,选择从session中获取
   */
  public static UserInfo getCurrentUser(HttpSession session) {
    Authentication authentication = getAuthentication(session);

    if (authentication == null) {

      return null;
    }

    Object principal = authentication.getPrincipal();
    if (!(principal instanceof UserInfo)) {
      return null;
    }
    return (UserInfo) principal;

  }

  /**
   * 取得当前用户, 返回值为User类
   */
  public static UserInfo getCurrentUser() {
    Authentication authentication = getAuthentication(null);

    if (authentication == null) {
      return null;
    }

    Object principal = authentication.getPrincipal();
    if (!(principal instanceof UserInfo)) {
      return null;
    }
    return (UserInfo) principal;

  }

  /**
   * 
   * <strong>Title : getCurrentUserAuthority<br>
   * </strong> <strong>Description : </strong>判断当前用户的权限，只限菜单权限<br>
   * <strong>Create on : 2014-2-25 下午04:30:25<br>
   * </strong>
   * <p>
   * 
   * @return Set<GrantedAuthority>
   * @throws
   * @author dapeng_li<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   *          <strong>修改历史:</strong><br>
   *          修改人 | 修改日期 | 修改描述<br>
   *          -------------------------------------------<br>
   * <br>
   * <br>
   */
  public static Boolean hasAuthorityCurrentUser(String name) {
    Set<GrantedAuthority> auths = (Set<GrantedAuthority>) getCurrentUser().getAuthorities();
    if (auths == null || auths.size() == 0) {
      return false;
    }
    for (GrantedAuthority auth : auths) {
      if (auth.getAuthority().equals(Constants.ROLEPREFIX + name)) {
        return true;
      } else {
        continue;
      }
    }
    return false;
  }

  /**
   * 
   * <strong>Title : hasButtonAuthorityCurrentUser<br></strong>
   * <strong>Description : </strong>用户的按钮权限<br> 
   * <strong>Create on : 2015-8-18 下午2:19:31<br></strong>
   * <p>
   * @param name
   * @return
   * Boolean
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  public static Boolean hasButtonAuthorityCurrentUser(String name) {
    Set<GrantedAuthority> auths = (Set<GrantedAuthority>) getCurrentUser().getButtonAuthorities();
    if (auths == null || auths.size() == 0) {
      return false;
    }
    for (GrantedAuthority auth : auths) {
      //超级管理员SA不需要过滤权限
      if(MyAccessDecisionManager.ALLACCESSDECIDION.equalsIgnoreCase(auth.getAuthority())){
        return true;
      }else if ((Constants.BOTTONPREFIX + name).equalsIgnoreCase(auth.getAuthority())) {
        return true;
      } else{
        continue;
      }
    }
    return false;
  }

  /**
   * 
   * <strong>Title : getSiteCode<br></strong>
   * <strong>Description : </strong>获取用户选择的工厂<br> 
   * <strong>Create on : 2015-8-7 上午9:30:56<br></strong>
   * <p>
   * @return
   * String
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  public static String getSiteCode() {
    UserInfo user = getCurrentUser();
    if (user != null && !StringUtils.isBlank(user.getSiteCode())) {
      return user.getSiteCode().trim();
    }

    return "1001";
  }

  public static String getLanguageCode() {
    UserInfo user = getCurrentUser();
    if (user != null && !StringUtils.isBlank(user.getLanguageCode())) {
      return user.getLanguageCode().trim();
    }

    return "zh";
  }

  public static String getJavaTimeZoneId() {
    UserInfo user = getCurrentUser();
    if (user != null && !StringUtils.isBlank(user.getTimeZoneCode())) {
      return user.getJavaTimeZoneId().trim();
    }

    return null;
  }

  /**
   * 
   * <strong>Title : getCurrentUserLoginIp<br></strong>
   * <strong>Description : </strong>获取当前登录用户的ip<br> 
   * <strong>Create on : 2015-8-31 上午10:26:22<br></strong>
   * <p>
   * @return
   * String
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  public static String getCurrentUserLoginIp() {
    Authentication authentication = getAuthentication(null);
    WebAuthenticationDetails wauth = (WebAuthenticationDetails) authentication.getDetails();
    return wauth.getRemoteAddress();
  }

  /**
   * 
   * <strong>Title : getCurrentUserMacAddress<br></strong>
   * <strong>Description : </strong>根据用户ip获取mac地址<br> 
   * <strong>Create on : 2015-8-31 上午10:36:50<br></strong>
   * <p>
   * @param ip
   * @return
   * String
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  public static String getCurrentUserMacAddress(String ip) {
    String str = null;
    String macAddress = null;
    try {
      Process p = Runtime.getRuntime().exec("nbtstat -A " + ip);
      InputStreamReader ir = new InputStreamReader(p.getInputStream(),"UTF-8");
      LineNumberReader input = new LineNumberReader(ir);
      for (int i = 1; i < 100; i++) {
        str = input.readLine();
        if (str != null && str.indexOf("MAC Address") > 1) {
          macAddress = str.substring(str.indexOf("MAC Address") + 14, str.length());
          break;
        }
      }
    } catch (IOException e) {
      log.error("{}", e);
    }
    return macAddress;
  }

  /**
   * 
   * <strong>Title : getCurrentUserSessionId<br></strong>
   * <strong>Description : </strong>获取用户当前会话id<br> 
   * <strong>Create on : 2015-8-31 上午10:36:31<br></strong>
   * <p>
   * @return
   * String
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  public static String getCurrentUserSessionId() {
    Authentication authentication = getAuthentication(null);
    WebAuthenticationDetails wauth = (WebAuthenticationDetails) authentication.getDetails();
    return wauth.getSessionId();
  }

  /**
   * 取得Authentication, 如当前SecurityContext为空时返回null.
   */
  private static Authentication getAuthentication(HttpSession session) {
    SecurityContext context = null;
    //从session获取
    if (session != null) {
      context = (SecurityContext) session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
    } else {
      context = SecurityContextHolder.getContext();
    }
    if (context == null) {
      return null;
    }

    return context.getAuthentication();
  }

  public static void clearContext() {
    SecurityContextHolder.clearContext();
  }
}
